import React from 'react'
import { Link, Route, Routes, Navigate } from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
import Login from './components/Login'
import Like from './components/Like'
import SecondFather from './components/SecondFather'
import SecondSonOne from './components/SecondSonOne'
import SecondSonTwo from './components/SecondSonTwo'
function App() {
  return (
    <div>
      {/* 
        核心组件：BrowerRouter
        作用：包裹整个应用，一个 React 应用只需要使用一次
        两种常用 Router：HashRouter 和 BrowserRouter
        HashRouter：
          使用 URL 的哈希值实现（http://localhost:3000/#/first）
        BrowserRouter（推荐）:
          使用 H5 的 history.pushState API 实现（http://localhost:3000/first）
      */}
      {/* 
        核心组件：Link
        作用：用于指定导航链接，完成路由跳转
        语法说明：组件通过 to 属性指定路由地址，最终会渲染为 a 链接元素
      */}
      {/* 
        核心组件：Routes
        作用：提供一个路由出口，满足条件的路由组件会渲染到组件内部
      */}
      {/* 
        核心组件：Route
        作用：指定导航链接，完成路由匹配
        语法说明：path 属性指定匹配的路径地址，element 属性指定要渲染的组件
      */}
      <h3>路由基本实现：</h3>
      {/* 点击跳转 */}
      <Link to="/">Home页</Link>
      <span>、</span>
      <Link to="/about">About页</Link>
      <span>、</span>
      <Link to="/like">Like页</Link>
      <span>、</span>
      <Link to="/login">Login页</Link>
      <span>、</span>
      <Link to="/secondFather">SecondFather二级路由父页</Link>
      {/* 配置路由位置 */}
      <Routes>
        {/* 普通路由 */}
        <Route
          path="/"
          element={<Home />}
        />
        {/* searchParams 传参 */}
        <Route
          path="/about"
          element={<About />}
        />
        {/* params 传参 */}
        <Route
          path="/like/:id"
          element={<Like />}
        />
        {/* 总跳转 */}
        <Route
          path="/login"
          element={<Login />}
        />

        {/* 二级路由，使用双标签包裹子页面 Route */}
        <Route
          path="/secondFather"
          element={<SecondFather />}>
          {/* 二级路由 */}
          {/* 重定向方法一： */}
          {/* <Route
            index
            element={<SecondSonOne />}
          /> */}
          {/* 重定向方法二： */}
          <Route
            path="/secondFather"
            element={<Navigate to="/secondFather/secondSonOne" />}
          />

          {/* 使用重定向方法一的时候记得把下面这个注释了，注意 SecondFather 组件中也要更改 */}
          <Route
            path="/secondFather/secondSonOne"
            element={<SecondSonOne />}
          />
          <Route
            path="/secondFather/secondSonTwo"
            element={<SecondSonTwo />}
          />
        </Route>
      </Routes>

      {/* 
        编程式导航-跳转：
        作用：通过 js 编程的方式进行路由页面跳转，比如从登录页跳转到关于页
        语法说明：
          1、导入 useNavigate 钩子函数
            import { useNavigate } from 'react-router-dom'
          2、执行钩子函数得到跳转函数
            const navigate = useNavigate()
          3、执行跳转函数完成跳转
            navigate('/about', { replace: true })
        注意：如果在跳转时不想加历史记录（返回不会跳转页面），可以添加额外参数 replace 为 true：navigate('/about', { replace: true })
        详情见 Login.jsx



        跳转携带参数：
        params 传参（通过动态路由传参）：
          使用：
            1、在需要接收参数的 Route 中配置动态路由：path="/like/:id"
            2、在传递参数的组件中，使用 Link 或 useNavigate() 传参，例如：const navigate = useNavigate()  navigate(`路径/${id}`)
            3、在需要接收参数的组件中，使用 useParams() 接收参数
          
        searchParams 传参（通过url的查询字符串传参）：
          使用：
            1、正常配置 Route
            2、在传递参数的组件中，使用 Link 或 useNavigate() 传参，例如：<Link to="/路径?name=mafei&age=20" /> 、 navigate('/about?id=1001')
            3、在需要接收参数的组件中，使用 useLocation() 或者 useSearchParams() 加上 Object.formEntries() 方法获得参数对象（推荐）

        1、params 传参（详情见 Login 和 About）
          传参：
            navigate('/about/1001')
          取参：
            const params = useParams() （得到一个参数对象）
        2、 searchParams 传参
          传参：
            navigate('/about?id=1001')
          取参方式1：
            const [params] = useSearchParams()
            const id = params.get('id')
          取参方式2：
            const [params] = useSearchParams()
            const data = Object.fromEntries(params) （得到一个参数对象）



        二级路由：
          使用：
            1、作为谁的二级路由，就用谁的路由的双标签包裹住即可
            2、在父组件当中，使用 <Outlet /> 占位，表示将子路由组件在此显示
          二级路由重定向：
            1、可以使用 index 将需要重定向的 Route 的 path 代替，但是这样网页无法显示包含子路由的完整路径
                注意在父组件中点击跳转的时候也要匹配，即 to 为空：<Link to="">secondSonOne页</Link>
              <Route
                index
                element={<组件 />}
              />
            2、页可以引入使用 Navigate ，将 element={<Navigate to="/父路由名/子路由名" />} ，这样可以显示完整路径
                注意在父组件中点击跳转的时候也要匹配，即 to 不为空：<Link to="secondSonOne">secondSonOne页</Link>
              import { Navigate } from 'react-router-dom'
              <Route
                path="/父路由名"
                element={<Navigate to="/父路由名/子路由名" />}
              />



        404 路由配置：
          语法：在各级路由的最后添加 * 号路由作为兜底
          <Route path="*" element={<404 组件 />}
      */}
    </div>
  )
}

export default App
